import { FormListConfig, Dictionary } from '@/typings';
type NoticeType = 'error' | 'success' | 'info' | 'warning';

export interface MessageConfig {
    message: string | any;
    type?: NoticeType;
    title?: string | any;
    duration?: number;
}

export interface ConfirmConfig {
    content: any;
    info?: string | any;
    confirmButtonText?: string;
    cancelButtonText?: string;
    type?: NoticeType;
}
export interface BarcodeRecordConfig {
    scanKeyword?: string;
    scanType: string;
    desc: string;
    status: string;
    infoText: string;
    time: Date;
    number: number;
}
export interface NoticeConfig {
    message: ({ message, type, title, duration }) => void;
    notify: ({ message, type, title, duration }) => void;
    confirm: ({ content, info, confirmButtonText, cancelButtonText, type }) => Promise<any>;
    prompt: ({ content, info, confirmButtonText, cancelButtonText, type }) => Promise<any>;
}

export const Notice: NoticeConfig = {
    message: function ({ message, type = 'info', title = this.$t('commonWord.tips'), duration = 2000 }: MessageConfig) {
        this.$message({
            showClose: true,
            title,
            message,
            type,
            duration
        });
    },
    notify: function ({ message, title = this.$t('commonWord.tips'), type = 'error' }: MessageConfig) {
        this.$notify({
            title,
            message,
            duration: 0,
            type
        });
    },
    confirm: function ({
        content,
        info = this.$t('commonWord.tips'),
        confirmButtonText = this.$t('commonWord.confirm'),
        cancelButtonText = this.$t('commonWord.cancel'),
        type = 'warning'
    }: ConfirmConfig) {
        return new Promise((resolve, reject) => {
            this.$confirm(content, info, {
                confirmButtonText,
                cancelButtonText,
                type
            })
                .then(() => {
                    resolve();
                })
                .catch((err: any) => {
                    reject(err);
                });
        });
    },
    prompt: function ({
        content,
        info = this.$t('commonWord.tips'),
        confirmButtonText = this.$t('commonWord.confirm'),
        cancelButtonText = this.$t('commonWord.cancel'),
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        type = 'warning'
    }: ConfirmConfig) {
        return new Promise((resolve, reject) => {
            this.$prompt(content, info, {
                confirmButtonText,
                cancelButtonText,
                inputPattern: /^[a-zA-Z0-9\u4e00-\u9fa5_ ]+$/,
                inputErrorMessage: this.$t('form.placeholder.input', {
                    msg: content
                })
            })
                .then(() => {
                    resolve();
                })
                .catch((err: any) => {
                    reject(err);
                });
        });
    }
};

export const Tools: any = {
    // toUpperCase
    // 小驼峰转换大驼峰
    toUpperCase: function (str: string): string {
        return str.replace(/_(-w)/g, function (a, b) {
            return b.toUpperCase();
        });
    },
    // 大驼峰转换小驼峰
    toLowerCase: function (str: string): string {
        return str.replace(/([A-Z])/g, function (a, b) {
            return '_' + b.toLowerCase();
        });
    },
    // 去除首尾空格
    trim: function (str: string): string {
        return str.replace(/^\s+|\s+$/g, '');
    },
    arrayToObjKey(arr: Pick<FormListConfig, 'value'>[]): Dictionary {
        const obj = {};
        arr.forEach((item) => {
            obj[item.value] = '';
        });
        return obj;
    },
    toBoolean: function (str: string): boolean {
        return str === 'true';
    },
    fIndex: function (arr: Array<{ value: string }>, name: String): number {
        return arr.findIndex((k) => k.value === name);
    },
    getCurrentData: function (showAll = true, dayline?: number) {
        const date = new Date();
        const year = date.getFullYear();
        const month = (date.getMonth() + 1).toString().padStart(2, '0');
        const strDate = dayline ? date.getDate() + dayline : date.getDate();
        const hours = date.getHours().toString().padStart(2, '0');
        const minus = date.getMinutes().toString().padStart(2, '0');
        if (showAll) {
            return `${year}-${month}-${strDate.toString().padStart(2, '0')} ${hours}:${minus}`;
        } else {
            return `${year}-${month}-${strDate.toString().padStart(2, '0')}`;
        }
    },
    forEachValue: function (obj: Object, fn: Function) {
        Object.keys(obj).forEach((key) => fn(obj[key], key));
    },
    // 带有父子级 数据 的扁平 包含 父元素
    withChildrenFlatten: function (arr: any[]) {
        return arr.reduce((k, m) => {
            const { children, ...rest } = m;
            if (children && children.length > 0) {
                k = k.concat([...Tools.withChildrenFlatten(children)]);
            }
            k.push(rest);
            return k;
        }, []);
    },
    withChildrenFlattenNoParent: function (arr: any[]) {
        return arr.reduce((k, m) => {
            const { children, ...rest } = m;
            if (children && children.length > 0) {
                k = k.concat([...Tools.withChildrenFlattenNoParent(children)]);
            }
            if (!children || (children && children.length === 0)) {
                k.push(rest);
            }
            return k;
        }, []);
    },
    // 多维数据的扁平
    flatten: function <T>(arr: T[], depth = 1) {
        return arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? Tools.flatten(v, depth - 1) : v), []);
    },

    // flattenObjArr<T>(objArr: T): any[] {
    //   var ret = []
    //   Object.keys(objArr).forEach(function(k) {
    //     ret.push.apply(ret, objArr[k])
    //   })
    //   return ret
    // },
    debounce(func: Function, delay: number): any {
        let timer: any;
        // const that: any = this
        return function () {
            const context = this;
            const args = arguments;
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => {
                func.apply(context, args);
            }, delay);
        };
    },
    formatNumber(n: string | any[]) {
        n = n.toString();
        return n[1] ? n : '0' + n;
    },
    // 参数number为毫秒时间戳，format为需要转换成的日期格式
    formatTime(number: number, format: any = 'Y-M-D') {
        const time: Date = new Date(number);
        const newArr: any[] = [];
        const formatArr = ['Y', 'M', 'D', 'h', 'm', 's'];
        newArr.push(time.getFullYear());
        newArr.push(Tools.formatNumber(time.getMonth() + 1));
        newArr.push(Tools.formatNumber(time.getDate()));
        newArr.push(Tools.formatNumber(time.getHours()));
        newArr.push(Tools.formatNumber(time.getMinutes()));
        newArr.push(Tools.formatNumber(time.getSeconds()));
        for (const i in newArr) {
            format = format.replace(formatArr[i], newArr[i]);
        }
        return format;
    },
    setValueAndName(val: any[], isNeedLinkLabel = false) {
        val.forEach((e) => {
            e.value = e.id;
            e.label = e.name;
            if (isNeedLinkLabel) e.linkLabel = e.linkLabel || e.name;
            // e.linkLabel = e.linkLabel || e.label;
            // eslint-disable-next-line no-prototype-builtins
            if (e.hasOwnProperty('children')) {
                if (isNeedLinkLabel) {
                    e.children.forEach((children) => {
                        children.linkLabel = `${e.linkLabel}/${children.name}`;
                        Tools.setValueAndName(e.children, isNeedLinkLabel);
                    });
                } else {
                    Tools.setValueAndName(e.children);
                }
            }
        });
    },
    // treeOptions.forEach(item => {
    //   item.linkLabel = item.linkLabel || item.label;
    //   if (item.children && item.children.length) {
    //     item.children.forEach(children => {
    //       children.linkLabel = `${item.linkLabel}/${children.label}`;
    //       formatTree(item.children);
    //     });
    //   }
    // });
    setOptions(val: any[], keys: string, arr: any[], optionsName = 'options') {
        const findArr = arr.filter((e) => {
            return e.matchSelectKey === keys || e.value === keys;
        });
        if (findArr.length) {
            findArr.forEach((item) => {
                item[optionsName] = val;
            });
        }
    },
    // 用于获取url参数
    getQueryVariable(url, variable) {
        var query = url.split('?')[1];
        if (query) {
            var vars = query.split('&');
            for (var i = 0; i < vars.length; i++) {
                var pair = vars[i].split('=');
                if (pair[0] === variable) {
                    return pair[1];
                }
            }
        }
        return '';
    },
    barcodeObj(item: any, type: string = 'success'): BarcodeRecordConfig {
        const SCAN_TYPE = {
            0: 'SKU',
            1: '条码',
            2: '唯一码',
            3: '箱号',
            4: '齐码(条码)',
            5: '齐码(SKU)'
        };
        const goodsName = `${item.goodsCode}-${item.goodsName}`;
        const skuDesc = item.skuName || `${goodsName}-${item.colorName}-${item.longName}-${item.sizeName}`;
        return {
            scanType: SCAN_TYPE[item.scanType],
            scanKeyword: item.scanKeyword,
            desc: [4, 5].includes(item.scanType) ? `${goodsName}-${item.colorName}` : [3].includes(item.scanType) ? item.boxCode : `${skuDesc}`,
            time: Tools.getCurrentData(),
            status: type,
            number: item.number,
            infoText: type === 'success' ? '扫码成功' : '扫码失败'
        };
    },
    // 判断空
    isEmpty: function (v: any) {
        switch (typeof v) {
            case 'undefined':
                return true;
            case 'string':
                if (v.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length === 0) return true;
                break;
            // case 'boolean':
            //   if (!v) return true
            //   break
            case 'number':
                if (v === 0 || isNaN(v)) return true;
                break;
            case 'object':
                if (v === null || v.length === 0) return true;
                for (const i in v) {
                    return false;
                }
                return true;
        }
        return false;
    },
    // 同步引入外链文件
    synchronizationLoad: function (url) {
        return new Promise((resolve) => {
            const script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = url;
            document.getElementsByTagName('head')[0].appendChild(script);
            script.onload = () => {
                resolve(true);
            };
            // eslint-disable-next-line handle-callback-err
            script.onerror = () => {
                resolve(false);
            };
        });
    },
    // 数组某个字段作为key转成对象[如果没有那个值则过滤掉/如果重复不会顶替]  没有/重复 都会出现在error
    array2object: function (key: string, array: Array<any>) {
        return array.reduce(
            (x, y) => {
                const { success, error } = x;
                if (!x[key] && y[key]) {
                    Object.assign(success, { [key]: y[key] });
                } else {
                    error.push(y);
                }
                return x;
            },
            { success: {}, error: [] }
        );
    }
};
